#include "safety_cmd.h"
#include "log/zuclog.h"
#include "motion/modbuscrc.h"
#include "motion/mot_priv.h"
#include "errcode.h"
#include "safety/mot/safety_recheck.h"
#include "rtdev/safetyboard/scbitf.h"
//#include "tp/tpmanager.hh"
#include "axisgroup/axisgroup_robot.h"
#include "axisgroup/axisgroup.h"
#include "axisgroup/robot_mgr.h"
#include "axisgroup/axisgroup_set.h"
#include "zuc/task/motion_al.h"
#include "axisgroup/pfsm_state.h"
#include <string.h>

#define MOTCMD_INFO(fmt, ...) zuclog_info("SAFETYCMD %d", fmt, group_id_, ##__VA_ARGS__)
#define MOTCMD_ERR(fmt, ...) zuclog_error("SAFETYCMD %d", fmt, group_id_, ##__VA_ARGS__)
#define MOTCMD_DEBUG(fmt, ...) zuclog_debug("SAFETYCMD %d", "[%06d] " fmt, group_id_, __LINE__, ##__VA_ARGS__)

#define MAX_ERROR_MSG_STR_LEN 256

int SafetyCmd::active_callback()
{
    //伟创力定制的手自动模式功能开启，且在自动模式下，禁止设置安全参数 || 正在运动中则禁止设置安全参数
    // if ((zucStatus->operation_mode_option == 1 && zucStatus->operation_mode == 1) || zucStatus->motion.traj.inpos != 1)
    // {
    //     zucOperatorError(NONMANUAL_CANNOT_SET_ROBOT_SAFETY_PARAMETERS,
    //                      "The safety parameters cannot be configured if the robot is not in manual mode or in manual mode motion.");
    //     return -1;
    // }
    // //如果程序执行则禁止设置安全参数
    // if (zucStatus->task.interpState == ZUC_TASK_INTERP_READING || zucStatus->task.interpState == ZUC_TASK_INTERP_PAUSED ||
    //     zucStatus->task.interpState == ZUC_TASK_INTERP_WAITING)
    // {
    //     zucOperatorError(PROGRAM_EXECUTE_CANNOT_SET_ROBOT_SAFETY_PARAMETERS, "The safety parameters cannot be configured if the program is being executed.");
    //     return -1;
    // };
    return 0;
}

static int task_init_finish_flag = 0;  // @FIXME liwang 该值由外部修改

int SafetyCmdSetCollisionSensitivity::active_callback()
{
    SafetyCmd::active_callback();
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    for (size_t i = 0; i < robot->joint_num(); i++)
    {
        if (this->joint_sensitivity_[i] < 0 || this->joint_sensitivity_[i] > 200)
        {
            MOTCMD_ERR("Invalid Para: joint_sensitivity[%d] = %d", i, joint_sensitivity_[i]);
            return -1;
        }
    }
    return 0;
}

int SafetyCmdSetCollisionSensitivity::process()
{
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    auto config = robot->get_set_intf()->get_usr_config();

    for (size_t i = 0; i < robot->joint_num(); i++)
    {
        config->robot_safety.collision.joint_sensitivity[i] = joint_sensitivity_[i];
        MOTCMD_INFO("joint_sensitivity[%d] = %d", i, zucmotStatus->joint_sensitivity[i]);
    }

    int ori_joint_sensitivity[ZUCMOT_MAX_JOINTS];
    for (int i = 0; i < zucmotConfig->numJoints; i++) { ori_joint_sensitivity[i] = zucmotConfig->safetyCfg.joint_collision_sensitivity[i]; }
    for (int i = 0; i < zucmotConfig->numJoints; i++) { zucmotConfig->safetyCfg.joint_collision_sensitivity[i] = joint_sensitivity_[i]; }
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    // @FIXME 7轴checksum 报错未修改
    zucmotStatus->safetyCRC = crc32((const uint8_t*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if ((ori_joint_sensitivity[0] != zucmotConfig->safetyCfg.joint_collision_sensitivity[0] ||
         ori_joint_sensitivity[1] != zucmotConfig->safetyCfg.joint_collision_sensitivity[1] ||
         ori_joint_sensitivity[2] != zucmotConfig->safetyCfg.joint_collision_sensitivity[2] ||
         ori_joint_sensitivity[3] != zucmotConfig->safetyCfg.joint_collision_sensitivity[3] ||
         ori_joint_sensitivity[4] != zucmotConfig->safetyCfg.joint_collision_sensitivity[4] ||
         ori_joint_sensitivity[5] != zucmotConfig->safetyCfg.joint_collision_sensitivity[5]) &&
        task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\", \"%d\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_joint_sensitivity[0],
                 ori_joint_sensitivity[1],
                 ori_joint_sensitivity[2],
                 ori_joint_sensitivity[3],
                 ori_joint_sensitivity[4],
                 ori_joint_sensitivity[5],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[0],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[1],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[2],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[3],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[4],
                 zucmotConfig->safetyCfg.joint_collision_sensitivity[5]);
        reportInfo(INFO_INIT_SAFETY_JOINT_SENSITIVITY_CHANGED, "checksum changed # %s ", str);
    };
    return 0;
}

int CmdSetForceLimitValue::active_callback()
{
    SafetyCmd::active_callback();
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);

    if (force_limit_value_ < 0 || force_limit_value_ > 200)
    {
        MOTCMD_ERR("Invalid Para: force_limit_value %d", force_limit_value_);
        return -1;
    }
    return 0;
}

int CmdSetForceLimitValue::process()
{
    MOTCMD_INFO("ZUCMOT_SET_FORCE_LIMIT_VALUE, %d\n", force_limit_value_);
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    auto config = robot->get_set_intf()->get_usr_config();
    config->robot_safety.collision.force_limit_value = force_limit_value_;

    int ori_force_limit;
    ori_force_limit = zucmotConfig->safetyCfg.force_limit;

    zucmotConfig->safetyCfg.force_limit = force_limit_value_;
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_force_limit != zucmotConfig->safetyCfg.force_limit && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_force_limit,
                 zucmotConfig->safetyCfg.force_limit);
        reportInfo(INFO_SAFETY_CONF_FORCE_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetCollisionDetectionEnable::active_callback()
{
    SafetyCmd::active_callback();
    if (collision_detection_enable_ < 0 || collision_detection_enable_ > 1)
    {
        MOTCMD_ERR("Invalid Para: collision_detection_enable %d", collision_detection_enable_);
        return -1;
    }
    return 0;
}

int CmdSetCollisionDetectionEnable::process()
{
    MOTCMD_INFO("ZUCMOT_SET_COLLISION_DETECTION_ENABLE, %d\n", collision_detection_enable_);
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    auto set_intf = robot->get_set_intf();
    set_intf->get_usr_config()->robot_safety.collision.collision_detection_enable = collision_detection_enable_;
    if (collision_detection_enable_)
    {
        auto cur_config = robot->get_robot_active_config();
        set_intf->set_collision_lv(cur_config.robot_safety.collision.clsn_sensitivity);  // 关闭伺服检测
    }
    else
    {
        set_intf->set_collision_lv(0);  // 关闭伺服检测
    }
    set_intf->config_change();

    int ori_colli;
    ori_colli = zucmotConfig->safetyCfg.collision_enable;

    zucmotConfig->safetyCfg.collision_enable = collision_detection_enable_;
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_colli != zucmotConfig->safetyCfg.collision_enable && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_colli,
                 zucmotConfig->safetyCfg.collision_enable);
        reportInfo(INFO_INIT_SAFETY_COLLISION_ENABLE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetRunMode::process()
{
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    int ori_motRunMode = robot->is_sim();
    robot->set_sim(mode_, serial_num_);
    MOTCMD_INFO("switch sim/real control mode: %s", robot->is_sim() ? "SIM" : "REAL");

    // #TODO
    // unsigned int ori_crc = zucmotStatus->safetyCRC;
    // zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    // if (ori_motRunMode != zucmotConfig->safetyCfg.motRunMode && task_init_finish_flag == 1)
    // {
    //     char str[MAX_ERROR_MSG_STR_LEN];
    //     snprintf(str,
    //              MAX_ERROR_MSG_STR_LEN,
    //              "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
    //              ori_crc,
    //              zucmotStatus->safetyCRC,
    //              ori_motRunMode,
    //              zucmotConfig->safetyCfg.motRunMode);
    //     reportInfo(INFO_SAFETY_CONF_RUN_MODE_CHANGED, "checksum changed # %s ", str);
    // }
    return 0;
}

int CmdSetFunctionSaftyPara::process()
{
    for (int i = 0; i < 2; i++)
    {
        zucmotStatus->robot_power_limit[i] = robot_power_limit_[i];
        zucmotStatus->robot_momentum_limit[i] = robot_momentum_limit_[i];
        zucmotStatus->robot_endforce_limit[i] = robot_endforce_limit_[i];
    }
    zucmotStatus->robot_velocity_limit = robot_velocity_limit_;

    MOTCMD_INFO("ZUCMOT_SET_FUNCTION_SAFTY_PARA: Safty Para, %lf, %lf, %lf, %lf, %lf, %lf, %lf\n",
                zucmotStatus->robot_power_limit[0],
                zucmotStatus->robot_power_limit[1],
                zucmotStatus->robot_momentum_limit[0],
                zucmotStatus->robot_momentum_limit[1],
                zucmotStatus->robot_endforce_limit[0],
                zucmotStatus->robot_endforce_limit[1],
                zucmotStatus->robot_velocity_limit);

    return 0;
}

int CmdSetJointMinLimits::active_callback()
{
    SafetyCmd::active_callback();
    if (joint_num_ < 0 || joint_num_ >= ZUCMOT_MAX_JOINTS)
    {
        return -1;
    }
    auto config = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_robot_active_config().robot_model.joint_para;
    if (config.default_joint_min_pos[joint_num_] > minLimit_)
    {
        MOTCMD_ERR("Cannot set a min limit value (%lf) less than the config (%lf)", minLimit_, config.default_joint_min_pos[joint_num_]);
        return -1;
    }
    return 0;
}

int CmdSetJointMinLimits::process()
{
    MOTCMD_INFO("ZUCMOT_SET_JOINT_MIN_LIMITS %d, %lf\n", joint_num_, minLimit_);
    double ori_min_limit;
    ori_min_limit = zucmotConfig->safetyCfg.negative_limit[joint_num_];

    auto set_intf = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_set_intf();
    int ret = set_intf->set_robot_joint_limit("JOINT_POS_MIN", joint_num_, minLimit_);
    if (ret)
    {
        return -1;
    }
    // #TODO checksum
    zucmotConfig->safetyCfg.negative_limit[joint_num_] = minLimit_;
    recheck_set_minjpos(minLimit_, joint_num_);
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_min_limit != zucmotConfig->safetyCfg.negative_limit[joint_num_] && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 joint_num_ + 1,
                 ori_min_limit,
                 zucmotConfig->safetyCfg.negative_limit[joint_num_]);
        reportInfo(INFO_SAFETY_CONF_JOINT_MIN_LIMITS_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetJointMaxLimits::active_callback()
{
    //伟创力定制的手自动模式功能开启，且在自动模式下，禁止设置安全参数 || 正在运动中则禁止设置安全参数
    // if ((zucStatus->operation_mode_option == 1 && zucStatus->operation_mode == 1) || zucStatus->motion.traj.inpos != 1)
    // {
    //     zucOperatorError(NONMANUAL_CANNOT_SET_ROBOT_SAFETY_PARAMETERS,
    //                      "The safety parameters cannot be configured if the robot is not in manual mode or in manual mode motion.");
    //     return -1;
    // }
    // //如果程序执行则禁止设置安全参数
    // if (zucStatus->task.interpState == ZUC_TASK_INTERP_READING || zucStatus->task.interpState == ZUC_TASK_INTERP_PAUSED ||
    //     zucStatus->task.interpState == ZUC_TASK_INTERP_WAITING)
    // {
    //     zucOperatorError(PROGRAM_EXECUTE_CANNOT_SET_ROBOT_SAFETY_PARAMETERS, "The safety parameters cannot be configured if the program is being executed.");
    //     return -1;
    // }

    if (joint_num_ < 0 || joint_num_ >= ZUCMOT_MAX_JOINTS)
    {
        return -1;
    }
    auto config = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_robot_active_config().robot_model.joint_para;
    if (config.default_joint_max_pos[joint_num_] < maxLimit_)
    {
        MOTCMD_ERR("Cannot set a max limit value (%lf) larger than the config (%lf)", maxLimit_, config.default_joint_max_pos[joint_num_]);
        return -1;
    }
    return 0;
}

int CmdSetJointMaxLimits::process()
{
    MOTCMD_INFO("ZUCMOT_SET_JOINT_MAX_LIMITS %d, %lf\n", joint_num_, maxLimit_);
    auto set_intf = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_set_intf();
    int ret = set_intf->set_robot_joint_limit("JOINT_POS_MAX", joint_num_, maxLimit_);
    if (ret)
    {
        return -1;
    }

    double ori_max_limit;
    ori_max_limit = zucmotConfig->safetyCfg.positive_limit[joint_num_];
    zucmotConfig->safetyCfg.positive_limit[joint_num_] = maxLimit_;
    recheck_set_maxjpos(maxLimit_, joint_num_);
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_max_limit != zucmotConfig->safetyCfg.positive_limit[joint_num_] && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 joint_num_ + 1,
                 ori_max_limit,
                 zucmotConfig->safetyCfg.positive_limit[joint_num_]);
        reportInfo(INFO_SAFETY_CONF_JOINT_MAX_LIMITS_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetRobotPowerLimit::process()
{
    if (zucmotConfig->cab_type >= 2)
    {
        float ori_power_limit;
        ori_power_limit = zucmotConfig->safetyCfg.robotPowerLimit;
        zucmotConfig->safetyCfg.robotPowerLimit = robotPowerLimit_;
        rtdev::RtDevMgr::instance().get_scb()->rob_power()->set_power(robotPowerLimit_, 0);
        // set_scb_robot_power_limit(robotPowerLimit_);
        MOTCMD_INFO("scb safety robot power limit: %f\n", robotPowerLimit_);
        unsigned int ori_crc = zucmotStatus->safetyCRC;
        zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
        if (ori_power_limit != zucmotConfig->safetyCfg.robotPowerLimit && task_init_finish_flag == 1)
        {
            char str[MAX_ERROR_MSG_STR_LEN];
            snprintf(str,
                     MAX_ERROR_MSG_STR_LEN,
                     "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                     ori_crc,
                     zucmotStatus->safetyCRC,
                     ori_power_limit,
                     zucmotConfig->safetyCfg.robotPowerLimit);
            reportInfo(INFO_SAFETY_CONF_ROBOT_POWER_LIMIT_CHANGED, "checksum changed # %s ", str);
        }
    }
    return 0;
}

int CmdSetTcpVelLimit::process()
{
    double ori_tcpVelLimit;
    ori_tcpVelLimit = zucmotConfig->safetyCfg.tcpVelLimit;
    zucmotConfig->safetyCfg.tcpVelLimit = tcpVelLimit_;
    recheck_set_maxtcpvel(tcpVelLimit_);
    //    tpmanager_SetSafe_tcpVelLimit(zucmotConfig->safetyCfg.tcpVelLimit);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_tcpVelLimit,
                 zucmotConfig->safetyCfg.tcpVelLimit);
        reportInfo(INFO_SAFETY_CONF_TCP_VEL_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetDragTcpSpeedLimit::process()
{
    double ori_dragTcpSpeedLimit;
    ori_dragTcpSpeedLimit = zucmotConfig->safetyCfg.dragTcpSpeedLimit;
    zucmotConfig->safetyCfg.dragTcpSpeedLimit = dragTcpSpeedLimit_;

    //当前拖拽速度限制是控制器在处理，屏蔽SCB/PSCB以切拖拽速度相关功能
    // set_scb_drag_tcp_speed_limit(dragTcpSpeedLimit);

    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_dragTcpSpeedLimit,
                 zucmotConfig->safetyCfg.dragTcpSpeedLimit);
        reportInfo(INFO_SAFETY_CONF_DRAG_TCP_VEL_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetStoppingDist::process()
{
    double ori_stoppingDist;
    ori_stoppingDist = zucmotConfig->safetyCfg.stoppingDist;
    zucmotConfig->safetyCfg.stoppingDist = stoppingDist_;
    recheck_set_stop_dist(stoppingDist_);
    //    tpmanager_SetSafe_stoppingDist(zucmotConfig->safetyCfg.stoppingDist);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_stoppingDist,
                 zucmotConfig->safetyCfg.stoppingDist);
        reportInfo(INFO_SAFETY_CONF_STOPPING_DIST_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetStoppingTime::process()
{
    double ori_stoppingTime;
    ori_stoppingTime = zucmotConfig->safetyCfg.stoppingTime;
    zucmotConfig->safetyCfg.stoppingTime = stoppingTime_;
    recheck_set_stop_time(stoppingTime_);
    //    tpmanager_SetSafe_stoppingtime(zucmotConfig->safetyCfg.stoppingTime);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_stoppingTime,
                 zucmotConfig->safetyCfg.stoppingTime);
        reportInfo(INFO_SAFETY_CONF_STOPPING_TIME_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetStoppingDistReduce::process()
{
    double ori_stoppingDist;
    ori_stoppingDist = zucmotConfig->safetyCfg.reduce_param.stopping_dist_reduce;
    zucmotConfig->safetyCfg.reduce_param.stopping_dist_reduce = stopping_dist_reduce_;
    recheck_set_stop_dist_reduce(stopping_dist_reduce_);
    //    tpmanager_SetSafe_stoppingDistReduce(zucmotConfig->safetyCfg.reduce_param.stopping_dist_reduce);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_stoppingDist,
                 zucmotConfig->safetyCfg.reduce_param.stopping_dist_reduce);
        reportInfo(INFO_SAFETY_CONF_STOPPING_DIST_REDUCE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetStoppingTimeReduce::process()
{
    double ori_stoppingTime;
    ori_stoppingTime = zucmotConfig->safetyCfg.reduce_param.stopping_time_reduce;
    zucmotConfig->safetyCfg.reduce_param.stopping_time_reduce = stopping_time_reduce_;
    recheck_set_stop_time_reduce(stopping_time_reduce_);
    //    tpmanager_SetSafe_stoppingtimeReduce(zucmotConfig->safetyCfg.reduce_param.stopping_time_reduce);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_stoppingTime,
                 zucmotConfig->safetyCfg.reduce_param.stopping_time_reduce);
        reportInfo(INFO_SAFETY_CONF_STOPPING_TIME_REDUCE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetElbowVelLimitReduce::process()
{
    double ori_elbowVelLimitReduce;
    ori_elbowVelLimitReduce = zucmotConfig->safetyCfg.reduce_param.elbow_vel_limit_reduce;
    zucmotConfig->safetyCfg.reduce_param.elbow_vel_limit_reduce = elbowVelLimitReduce_;
    recheck_set_maxelbowvel_reduce(elbowVelLimitReduce_);
    //    tpmanager_SetSafe_elbowVelLimitReduce(zucmotConfig->safetyCfg.reduce_param.elbow_vel_limit_reduce);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_elbowVelLimitReduce,
                 zucmotConfig->safetyCfg.reduce_param.elbow_vel_limit_reduce);
        reportInfo(INFO_SAFETY_CONF_ELBOW_VEL_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetTcpVelLimitReduce::process()
{
    double ori_TCPVelLimitReduce;
    ori_TCPVelLimitReduce = zucmotConfig->safetyCfg.reduce_param.tcp_vel_reduce;
    zucmotConfig->safetyCfg.reduce_param.tcp_vel_reduce = tcpVelLimitReduce_;
    recheck_set_maxtcpvel_reduce(tcpVelLimitReduce_);
    //    tpmanager_SetSafe_tcpVelLimitReduce(zucmotConfig->safetyCfg.reduce_param.tcp_vel_reduce);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_TCPVelLimitReduce,
                 zucmotConfig->safetyCfg.reduce_param.tcp_vel_reduce);
        reportInfo(INFO_SAFETY_CONF_TCP_VEL_LIMIT_REDUCE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetMomentumLimitReduce::process()
{
    double ori_RobotMomentumLimitReduce;
    ori_RobotMomentumLimitReduce = zucmotConfig->safetyCfg.reduce_param.robot_momentum_limit_reduce;
    zucmotConfig->safetyCfg.reduce_param.robot_momentum_limit_reduce = momentumLimitReduce_;
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_RobotMomentumLimitReduce,
                 zucmotConfig->safetyCfg.reduce_param.robot_momentum_limit_reduce);
        reportInfo(INFO_SAFETY_CONF_MOMENTUM_LIMIT_REDUCE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetRobotPowerLimitReduce::process()
{
    double ori_RobotPowerLimitReduce;
    ori_RobotPowerLimitReduce = zucmotConfig->safetyCfg.reduce_param.robot_poewr_limit_reduce;
    zucmotConfig->safetyCfg.reduce_param.robot_poewr_limit_reduce = robotPowerLimitReduce_;
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_RobotPowerLimitReduce,
                 zucmotConfig->safetyCfg.reduce_param.robot_poewr_limit_reduce);
        reportInfo(INFO_SAFETY_CONF_ROBOT_POWER_LIMIT_REDUCE_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetMomentumLimit::process()
{
    double ori_momLimit;
    ori_momLimit = zucmotConfig->safetyCfg.momentumLimitValue;
    zucmotConfig->safetyCfg.momentumLimitValue = momentumLimit_;
    MOTCMD_INFO("ZUCMOT_SET_MOMENTUM_LIMIT %lf\n", zucmotConfig->safetyCfg.momentumLimitValue);
    zucmot_config_change();
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_momLimit,
                 zucmotConfig->safetyCfg.momentumLimitValue);
        reportInfo(INFO_SAFETY_CONF_MOMENTUM_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetJointVelLimit::active_callback()
{
    SafetyCmd::active_callback();
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    auto config = robot->get_robot_active_config().robot_model.joint_para;
    if (joint_num_ < 0 || joint_num_ >= (int)robot->joint_num())
    {
        return -1;
    }
    if (vel_ > config.default_joint_vel_limit[joint_num_])
    {
        MOTCMD_ERR("Joint %d velocity limit %f is larger than default joint velocity limit %f", joint_num_, vel_, config.default_joint_vel_limit[joint_num_]);
        return -1;
    };
    return 0;
}

int CmdSetJointVelLimit::process()
{
    if (vel_ < 0.0)
    {
        vel_ = 0.0;
    }
    MOTCMD_INFO("SET_JOINT_VEL_LIMIT %d: %f", joint_num_, vel_);
    auto set_intf = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_set_intf();
    int ret = set_intf->set_robot_joint_limit("JOINT_VEL_LIMIT", joint_num_, vel_);
    if (ret)
    {
        return -1;
    }

    double ori_vel_limit;
    ori_vel_limit = zucmotConfig->safetyCfg.jointVelLimit[joint_num_];
    recheck_set_maxjvel(vel_, joint_num_);
    zucmotConfig->safetyCfg.jointVelLimit[joint_num_] = vel_;
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_vel_limit != zucmotConfig->safetyCfg.jointVelLimit[joint_num_] && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 joint_num_ + 1,
                 ori_vel_limit,
                 zucmotConfig->safetyCfg.jointVelLimit[joint_num_]);
        reportInfo(INFO_SAFETY_CONF_JOINT_VEL_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetJointErrLimit::active_callback()
{
    auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);
    if (joint_num_ < 0 || joint_num_ >= (int)robot->joint_num())
    {
        return -1;
    }
    if (errPosLimit_ < 0 || errPosLimit_ > 100)
    {
        MOTCMD_ERR("Joint %d error limit %f is out of range", joint_num_, errPosLimit_);
        return -1;
    }
    return 0;
}

int CmdSetJointErrLimit::process()
{
    MOTCMD_INFO("ZUCMOT_SET_JOINT_ERR_LIMIT %d: %lf\n", joint_num_, errPosLimit_);
    auto set_intf = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_)->get_set_intf();
    int ret = set_intf->set_robot_joint_limit("JOINT_ERR_LIMIT", joint_num_, errPosLimit_);
    if (ret)
    {
        return -1;
    }

    double ori_tol_limit;
    ori_tol_limit = zucmotConfig->safetyCfg.jointErrLimit[joint_num_];
    zucmotConfig->safetyCfg.jointErrLimit[joint_num_] = errPosLimit_;
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_tol_limit != zucmotConfig->safetyCfg.jointErrLimit[joint_num_] && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 MAX_ERROR_MSG_STR_LEN,
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%.3f\",\"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 joint_num_ + 1,
                 ori_tol_limit,
                 zucmotConfig->safetyCfg.jointErrLimit[joint_num_]);
        reportInfo(INFO_SAFETY_CONF_JOINT_ERR_LIMIT_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdTaskInitFinish::process()
{
    MOTCMD_INFO("[MOTINIT] init finish  \n");
    task_init_finish_flag = 1;
    return 0;
}

int CmdInitSafetyCrc::process()
{
    MOTCMD_INFO("ZUCMOT_INIT_SAFETY_CRC %#x \n", checksum_);
    zucmotStatus->safetyCRC = checksum_;
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != 0 && ori_crc != zucmotStatus->safetyCRC)
    {
        char str[100];
        snprintf(str, 100, "{\"fixed_key\":[\"%#x\", \"%#x\"]}", ori_crc, zucmotStatus->safetyCRC);
        reportInfo(INFO_INIT_SAFETY_CRC_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetSafeZoneElbowWristSphere::process()
{
    MOTCMD_INFO("ZUCMOT_SET_SAFE_ZONE_ELBOW_WRIST_SPHERE %lf, %lf", safezone_elbow_radius_, safezone_elbow_offest_);
    zucmotConfig->safetyCfg.elbow_sphere_radius = safezone_elbow_radius_;
    recheck_set_elbow_radius(safezone_elbow_radius_);
    zucmotConfig->safetyCfg.elbow_center_offset = safezone_elbow_offest_;
    zucmot_config_change();
    return 0;
}

static int check_single_safeplane_cfg_changed(SafePlane ori_zone, SafePlane now_zone)
{
    if ((ori_zone.enable != now_zone.enable) || (ori_zone.modify != now_zone.modify) || (ori_zone.safeD != now_zone.safeD) || (ori_zone.d != now_zone.d))
    {
        return INFO_SAFE_ZONE_SINGLE_CONF_CHANGED;
    }
    else if (memcmp(&ori_zone.planePoints, &now_zone.planePoints, sizeof(now_zone.planePoints)) ||
             memcmp(&ori_zone.safePoint, &now_zone.safePoint, sizeof(now_zone.safePoint)) || memcmp(&ori_zone.norm, &now_zone.norm, sizeof(now_zone.norm)))
    {
        return INFO_SAFE_ZONE_SINGLE_PLANE_CHANGED;
    }
    else
        return 0;
}

int CmdSetSafeZone::process()
{
    SafeZone ori_zone;
    ori_zone = zucmotConfig->safetyCfg.zone;
    zucmotConfig->safetyCfg.zone = zone_;
    recheck_set_safe_zone(zone_);
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        if ((ori_zone.autoEnable != zucmotConfig->safetyCfg.zone.autoEnable) ||
            (ori_zone.elbow_pos_limit_enable != zucmotConfig->safetyCfg.zone.elbow_pos_limit_enable) ||
            (ori_zone.openEnable != zucmotConfig->safetyCfg.zone.openEnable) || (ori_zone.safe != zucmotConfig->safetyCfg.zone.safe) ||
            (ori_zone.safeZoneMode != zucmotConfig->safetyCfg.zone.safeZoneMode) || (ori_zone.type != zucmotConfig->safetyCfg.zone.type) ||
            (ori_zone.wrist_pos_limit_enable != zucmotConfig->safetyCfg.zone.wrist_pos_limit_enable))
        {
            char str[MAX_ERROR_MSG_STR_LEN];
            snprintf(str,
                     MAX_ERROR_MSG_STR_LEN,
                     "{\"fixed_key\":[\"%#x\", \"%#x\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\", \"%d\",\"%d\",\"%d\",\"%d\"]}",
                     ori_crc,
                     zucmotStatus->safetyCRC,
                     ori_zone.type,
                     ori_zone.openEnable,
                     ori_zone.autoEnable,
                     ori_zone.safeZoneMode,
                     ori_zone.elbow_pos_limit_enable,
                     zucmotConfig->safetyCfg.zone.type,
                     zucmotConfig->safetyCfg.zone.openEnable,
                     zucmotConfig->safetyCfg.zone.autoEnable,
                     zucmotConfig->safetyCfg.zone.safeZoneMode,
                     zucmotConfig->safetyCfg.zone.elbow_pos_limit_enable);
            reportInfo(INFO_SAFE_ZONE_GLOBAL_CONF_CHANGED, "checksum changed # %s ", str);
        }

        for (int i = 0; i < 6; i++)
        {
            int check_ret = check_single_safeplane_cfg_changed(ori_zone.zone.plane[i], zone_.zone.plane[i]);
            if (check_ret == INFO_SAFE_ZONE_SINGLE_CONF_CHANGED)
            {
                char str[1024];
                snprintf(str,
                         1024,
                         "{\"fixed_key\":[\"%#x\", \"%#x\",\"%d\",\"%s\",\"%d\",\"%d\",\"%f\",\"%f\",\"%s\",\"%d\",\"%d\",\"%f\",\"%f\"]}",
                         ori_crc,
                         zucmotStatus->safetyCRC,
                         i,
                         ori_zone.zone.plane[i].name,
                         ori_zone.zone.plane[i].enable,
                         ori_zone.zone.plane[i].modify,
                         ori_zone.zone.plane[i].d,
                         ori_zone.zone.plane[i].safeD,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].name,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].enable,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].modify,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].d,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safeD);
                reportInfo(INFO_SAFE_ZONE_SINGLE_CONF_CHANGED, "checksum changed # %s ", str);
            }
            if (check_ret == INFO_SAFE_ZONE_SINGLE_PLANE_CHANGED)
            {
                char str[1024];
                snprintf(str,
                         1024,
                         "{\"fixed_key\":[\"%#x\", "
                         "\"%#x\",\"%d\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\","
                         "\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\","
                         "\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\",\"(%.3f;%.3f;%.3f;%.3f;%.3f;%.3f)\"]}",
                         ori_crc,
                         zucmotStatus->safetyCRC,
                         i,
                         ori_zone.zone.plane[i].planePoints[0].point.x,
                         ori_zone.zone.plane[i].planePoints[0].point.y,
                         ori_zone.zone.plane[i].planePoints[0].point.z,
                         ori_zone.zone.plane[i].planePoints[0].rpy.y,
                         ori_zone.zone.plane[i].planePoints[0].rpy.p,
                         ori_zone.zone.plane[i].planePoints[0].rpy.r,
                         ori_zone.zone.plane[i].planePoints[1].point.x,
                         ori_zone.zone.plane[i].planePoints[1].point.y,
                         ori_zone.zone.plane[i].planePoints[1].point.z,
                         ori_zone.zone.plane[i].planePoints[1].rpy.y,
                         ori_zone.zone.plane[i].planePoints[1].rpy.p,
                         ori_zone.zone.plane[i].planePoints[1].rpy.r,
                         ori_zone.zone.plane[i].planePoints[2].point.x,
                         ori_zone.zone.plane[i].planePoints[2].point.y,
                         ori_zone.zone.plane[i].planePoints[2].point.z,
                         ori_zone.zone.plane[i].planePoints[2].rpy.y,
                         ori_zone.zone.plane[i].planePoints[2].rpy.p,
                         ori_zone.zone.plane[i].planePoints[2].rpy.r,
                         ori_zone.zone.plane[i].safePoint.point.x,
                         ori_zone.zone.plane[i].safePoint.point.y,
                         ori_zone.zone.plane[i].safePoint.point.z,
                         ori_zone.zone.plane[i].safePoint.rpy.y,
                         ori_zone.zone.plane[i].safePoint.rpy.p,
                         ori_zone.zone.plane[i].safePoint.rpy.r,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.x,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.z,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].rpy.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].rpy.p,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].rpy.r,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.x,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.z,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].rpy.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].rpy.p,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].rpy.r,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].point.x,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].point.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].point.z,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].rpy.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].rpy.p,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[2].rpy.r,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.point.x,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.point.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.point.z,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.rpy.y,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.rpy.p,
                         zucmotConfig->safetyCfg.zone.zone.plane[i].safePoint.rpy.r);
                reportInfo(INFO_SAFE_ZONE_SINGLE_PLANE_CHANGED, "checksum changed # %s ", str);
            }
        }
    }
    int safeZone_elbow_wrist = 0;
    if (zucmotConfig->safetyCfg.zone.elbow_pos_limit_enable)
    {
        // double angle[ZUCMOT_MAX_JOINTS] = {0.0};
        // safeZone_elbow_wrist = 1;
        // for (int joint_num = 0; joint_num < zucmotConfig->numJoints; joint_num++) { angle[joint_num] = joints[joint_num].pos_cmd; }
        // kinematicsForward_elbow(angle, &zucmotStatus->carte_elbow_pos_cmd, &zucmotConfig->base_offset, &zucmotConfig->user_offset);
        // int check_safezone = checkSafezone(zucmotConfig->safetyCfg.zone,
        //                                    zucmotStatus->carte_pos_cmd,
        //                                    zucmotStatus->carte_elbow_pos_cmd,
        //                                    safeZone_elbow_wrist,
        //                                    zucmotConfig->safetyCfg.elbow_sphere_radius,
        //                                    zucmotConfig->user_offset,
        //                                    0,
        //                                    &zucmotStatus->checksafefalg);
    }
    for (int i = 0; i < 6; i++)
    {
        if (zucmotConfig->safetyCfg.zone.zone.plane[i].enable)
        {
            // MOTCMD_INFO("-----vrep elbow limit test out %d ------\n", i);
            // MOTCMD_INFO("the open safezone num is %d \n", i);
            // MOTCMD_INFO("point x y z is : %f %f %f \n",
            //             zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.x / 1000,
            //             zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.y / 1000,
            //             zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.z / 1000);
            zucmotConfig->verp_safe_information.plane[i].enable = 1;
            PmCartesian planePoints_vrep;
            planePoints_vrep.x = zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.x / 1000;
            planePoints_vrep.y = zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.y / 1000;
            planePoints_vrep.z = zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.z / 1000;
            zucmotConfig->verp_safe_information.plane[i].planePoints = planePoints_vrep;
            PmCartesian plant_x_aix, plant_x_aix_unit, plant_y_aix, plant_y_aix_unit, plant_x_aix1, plant_x_aix_unit1;
            PmEulerXyz PmEulerXYZ;
            plant_x_aix.x =
                zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.x - zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.x;
            plant_x_aix.y =
                zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.y - zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.y;
            plant_x_aix.z =
                zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[0].point.z - zucmotConfig->safetyCfg.zone.zone.plane[i].planePoints[1].point.z;
            pmCartUnit(&plant_x_aix, &plant_x_aix_unit);
            pmCartCartCross(&zucmotConfig->safetyCfg.zone.zone.plane[i].norm.point, &plant_x_aix_unit, &plant_y_aix);
            pmCartUnit(&plant_y_aix, &plant_y_aix_unit);
            pmCartCartCross(&plant_y_aix, &zucmotConfig->safetyCfg.zone.zone.plane[i].norm.point, &plant_x_aix1);
            pmCartUnit(&plant_x_aix1, &plant_x_aix_unit1);
            PmRotationMatrix m_plant;
            m_plant.x = plant_x_aix_unit1;
            m_plant.y = plant_y_aix_unit;
            m_plant.z = zucmotConfig->safetyCfg.zone.zone.plane[i].norm.point;
            pmMatXyzConvert(&m_plant, &PmEulerXYZ);
            zucmotConfig->verp_safe_information.plane[i].plane_Xyz = PmEulerXYZ;
            // MOTCMD_INFO("plant rx ry rz is : %f %f %f \n", PmEulerXYZ.x * 180 / PM_PI, PmEulerXYZ.y * 180 / PM_PI, PmEulerXYZ.z * 180 / PM_PI);
        }
        else
        {
            zucmotConfig->verp_safe_information.plane[i].enable = 0;
        }
    }
    zucmot_config_change();
    return 0;
}

int CmdSetSafeZoneEnable::process()
{
    MOTCMD_INFO("CmdSetSafeZoneEnable %d, zucmotStatus->is_safezone_limited:%d", enable_, zucmotStatus->is_safezone_limited);
    zucmotConfig->safeZoneEnable = enable_;
    if (zucmotConfig->safeZoneEnable)
    {
        checkSafezone(zucmotConfig->safetyCfg.zone,
                      zucmotStatus->carte_pos_cmd,
                      zucmotStatus->carte_elbow_pos_cmd,
                      0,
                      zucmotConfig->safetyCfg.elbow_sphere_radius,
                      zucmotConfig->user_offset,
                      0,
                      &zucmotStatus->checksafefalg);
    }
    zucmot_config_change();
    return 0;
}

int CmdSetOneKeyOp::process()
{
    MOTCMD_INFO("CmdSetOneKeyOp, %d, %d", onekeyenable_, autoprogram_);
    int ori_onekeyenable, ori_autoprog;
    ori_onekeyenable = zucmotConfig->safetyCfg.onekeyenable;
    ori_autoprog = zucmotConfig->safetyCfg.autoprogram;
    // zucmotStatus->auto_op_setting = auto_op_setting_;
    zucmotStatus->onekeyenable = onekeyenable_;
    zucmotStatus->autoprogram = autoprogram_;
    zucmotConfig->safetyCfg.onekeyenable = onekeyenable_;
    zucmotConfig->safetyCfg.autoprogram = autoprogram_;
    if (!zucmotStatus->maintenance_status)
    {
        unsigned int ori_crc = zucmotStatus->safetyCRC;
        zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
        //MOTCMD_INFO("[command] autowork.filename : %s", zucmotConfig->safetyCfg.autoWork.filename);
        if (ori_onekeyenable != zucmotConfig->safetyCfg.onekeyenable && task_init_finish_flag == 1)
        {
            char str[MAX_ERROR_MSG_STR_LEN];
            snprintf(str,
                     MAX_ERROR_MSG_STR_LEN,
                     "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
                     ori_crc,
                     zucmotStatus->safetyCRC,
                     ori_onekeyenable,
                     zucmotConfig->safetyCfg.onekeyenable);
            reportInfo(INFO_SAFETY_CONF_ONE_KEY_ENABLE_CHANGED, "checksum changed # %s ", str);
        }
        if (ori_autoprog != zucmotConfig->safetyCfg.autoprogram && task_init_finish_flag == 1)
        {
            char str[MAX_ERROR_MSG_STR_LEN];
            snprintf(str,
                     MAX_ERROR_MSG_STR_LEN,
                     "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
                     ori_crc,
                     zucmotStatus->safetyCRC,
                     ori_autoprog,
                     zucmotConfig->safetyCfg.autoprogram);
            reportInfo(INFO_SAFETY_CONF_AUTOPROGRAM_CHANGED, "checksum changed # %s ", str);
        }
    }
    return 0;
}

int CmdServoSetParam::active_callback()
{
    auto status = mot::al::MotionProxy::instance().robot(group_id_)->get_status();
    if (!status.is_power_on)
    {
        MOTCMD_ERR("CANNOT SET PARAMETER WHEN ROBOT IS NOT POWER ON");
    }
    switch (param_.paramType)
    {
    case ServoParam::CLSN_SENSITIVITY: {
        if (status.robot_config.robot_safety.collision.collision_detection_enable == 0)
        {
            // 碰撞被关闭，伺服的力限制不能被更改
            return -1;
        }
        if ((axisgroup::PFsmState::PlanMode)status.plan_mode == axisgroup::PFsmState::PlanMode::PLAN_DRAG)
        {
            reportError(CANNOT_SET_COLLISION_SENSITIVITY, ("cannot set collision sensitivity in drag mode or force control mode"));
            return -1;
        }
        if (param_.paramVal.clsn_sensitivity < 0 || param_.paramVal.clsn_sensitivity > 7)
        {
            MOTCMD_ERR("INVALID_COLLISION_SENSITIVITY %d", param_.paramVal.clsn_sensitivity);
            return -1;
        }
        break;
    }
    case ServoParam::BRAKE_CRTL_PARAM: {
        break;
    }
    case ServoParam::MULTI_TURN_STEP: {
        break;
    }
    case ServoParam::TORQUE_FORWARD_ENA: {
        break;
    }
    default: {
        break;
    }
    }
    return 0;
}

int CmdServoSetParam::process()
{
    switch (param_.paramType)
    {
    case ServoParam::CLSN_SENSITIVITY: {
        MOTCMD_INFO("CmdServoSetParam:CLSN_SENSITIVITY %d\n", param_.paramVal.clsn_sensitivity);
        auto robot = axisgroup::AxisGroupMgr::instance().get_axisgroup(group_id_);

        robot->get_set_intf()->set_collision_lv(param_.paramVal.clsn_sensitivity);

        int force_limit_convert[] = {10, 30, 50, 70, 90, 100, 100, 100};
        int fc_limit = force_limit_convert[param_.paramVal.clsn_sensitivity];  // #TODO LW

        int ori_sensitivity;
        ori_sensitivity = zucmotConfig->safetyCfg.clsn_sensitivity;
        zucmotConfig->safetyCfg.clsn_sensitivity = param_.paramVal.clsn_sensitivity;
        unsigned int ori_crc = zucmotStatus->safetyCRC;
        zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
        if (ori_sensitivity != zucmotConfig->safetyCfg.clsn_sensitivity && task_init_finish_flag == 1)
        {
            char str[MAX_ERROR_MSG_STR_LEN];
            snprintf(str,
                     MAX_ERROR_MSG_STR_LEN,
                     "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\",\"%d\"]}",
                     ori_crc,
                     zucmotStatus->safetyCRC,
                     ori_sensitivity,
                     zucmotConfig->safetyCfg.clsn_sensitivity);
            reportInfo(INFO_SAFETY_CONF_CLSN_SENSITIVITY_CHANGED, "checksum changed # %s ", str);
        }
        break;
    }
    case ServoParam::BRAKE_CRTL_PARAM: {
        // MOTCMD_INFO("CmdServoSetParam:BRAKE_CRTL_PARAM %d, %d\n", param_.paramVal.brakeCmd.jointId, param_.paramVal.brakeCmd.releaseBrake);
        // int releaseVal = (param_.paramVal.brakeCmd.releaseBrake != 0);
        // set_robot_joint_brake_lease(param_.paramVal.brakeCmd.jointId, releaseVal);
        break;
    }
    case ServoParam::MULTI_TURN_STEP: {
        // MOTCMD_INFO("CmdServoSetParam:MULTI_TURN_STEP %d, %d\n", param_.paramVal.brakeCmd.jointId, param_.paramVal.multiTurnCmd.multiTurnStep);
        // int multiTurnStep = 0;
        // if (param_.paramVal.multiTurnCmd.multiTurnStep > 0)
        //     multiTurnStep = 1;
        // else if (param_.paramVal.multiTurnCmd.multiTurnStep < 0)
        //     multiTurnStep = -1;
        // set_robot_joint_multi_turn_step(param_.paramVal.multiTurnCmd.jointId, multiTurnStep);
        break;
    }
    case ServoParam::TORQUE_FORWARD_ENA: {
        // MOTCMD_INFO("CmdServoSetParam:TORQUE_FORWARD_ENA %d\n", param_.paramVal.torque_forward_ena);
        // if (!GET_MOTION_INPOS_FLAG())
        // {
        //     reportError(CANNOT_SET_TORQUE_FORWARD_OPTION, ("cannot set torque forward option when robot is moving"));
        //     break;
        // }
        // zucmotConfig->torque_forward_ena = (param_.paramVal.torque_forward_ena != 0);
        // set_robot_torque_forward_enable(zucmotConfig->torque_forward_ena);
        break;
    }
    default: {
        // MOTCMD_INFO("[command] set servo param jointId:%d ,param:%d ,value:%d ",
        //             param_.paramVal.geneCmd.jointId,
        //             param_.paramVal.geneCmd.paramId,
        //             param_.paramVal.geneCmd.value);
        // if (param_.paramVal.geneCmd.jointId == -1)
        // {
        //     for (int i = 0; i < zucmotConfig->numJoints; i++) { set_general_servo_param(i, param_.paramVal.geneCmd.paramId, param_.paramVal.geneCmd.value); }
        // }
        // else
        // {
        //     set_general_servo_param(param_.paramVal.geneCmd.jointId, param_.paramVal.geneCmd.paramId, param_.paramVal.geneCmd.value);
        // }
        break;
    }
    }
    return 0;
}

int CmdSetAutoWork::process()
{
    MOTCMD_INFO("CmdSetAutoWork %d, %s", enable_, filename_);
    AutoWorkConfig ori_autoWork;
    ori_autoWork = zucmotConfig->safetyCfg.autoWork;
    // zucmotStatus->auto_op_setting = auto_op_setting_;
    zucmotConfig->safetyCfg.autoWork.enable = enable_;
    strncpy(zucmotConfig->safetyCfg.autoWork.filename, filename_, 256);
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    //MOTCMD_INFO("[command] autowork.filename : %s", zucmotConfig->safetyCfg.autoWork.filename);
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[1024];  // 存储转换后的字符串
        snprintf(str,
                 sizeof(str),
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%s\", \"%d\", \"%s\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_autoWork.enable,
                 ori_autoWork.filename,
                 enable_,
                 filename_);
        reportInfo(INFO_SAFETY_CONF_AUTO_WORK_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}

int CmdSetAttitudeSafety::process()
{
    // zuc_set_attitude_safety ori_attitudesafety;
    // ori_attitudesafety = zucmotConfig->safetyCfg.attitudesafety;
    // zucmotConfig->safetyCfg.attitudesafety = setattitudesafety_;
    // recheck_set_tool_ori(setattitudesafety_);
    // unsigned int ori_crc = zucmotStatus->safetyCRC;
    // zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    // if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    // {
    //     char str[MAX_ERROR_MSG_STR_LEN];
    //     snprintf(str,
    //              sizeof(str),
    //              "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%d\", \"%d\", "
    //              "\"%d\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%.2f\", \"%d\", \"%d\"]}",
    //              ori_crc,
    //              zucmotStatus->safetyCRC,
    //              ori_attitudesafety.conical_tip_choice,
    //              ori_attitudesafety.tool_properties_tilt,
    //              ori_attitudesafety.tool_properties_pan,
    //              ori_attitudesafety.deviation,
    //              ori_attitudesafety.deviation_warning,
    //              ori_attitudesafety.conical_cenrpy[0],
    //              ori_attitudesafety.conical_cenrpy[1],
    //              ori_attitudesafety.conical_cenrpy[2],
    //              ori_attitudesafety.enableLimAttitudeSafetyAuto,
    //              ori_attitudesafety.enableLimAttitudeSafetyOpen,
    //              setattitudesafety_.conical_tip_choice,
    //              setattitudesafety_.tool_properties_tilt,
    //              setattitudesafety_.tool_properties_pan,
    //              setattitudesafety_.deviation,
    //              setattitudesafety_.deviation_warning,
    //              setattitudesafety_.conical_cenrpy[0],
    //              setattitudesafety_.conical_cenrpy[1],
    //              setattitudesafety_.conical_cenrpy[2],
    //              setattitudesafety_.enableLimAttitudeSafetyAuto,
    //              setattitudesafety_.enableLimAttitudeSafetyOpen);
    //     reportInfo(INFO_SAFETY_CONF_ATTITUDE_SAFETY_CHANGED, "checksum changed # %s ", str);
    // }
    // double angle[ZUCMOT_MAX_JOINTS] = {0.0};
    // for (int joint_num = 0; joint_num < zucmotConfig->numJoints; joint_num++) { angle[joint_num] = joints[joint_num].pos_cmd; }

    // PmRpy tool_verp_rpy;
    // PmEulerXyz tool_dir_xyz;

    // PmRotationMatrix tool_verp_mat;
    // PmRotationMatrix to6_tool_verp_mat;

    // PmEulerXyz cone_xyz;

    // PmRotationMatrix mat_Rx, mat_Rz, mat_Rxz;
    // double RxReg = zucmotConfig->safetyCfg.attitudesafety.tool_properties_tilt * PM_PI / 180;
    // double RzReg = zucmotConfig->safetyCfg.attitudesafety.tool_properties_pan * PM_PI / 180;
    // pmRxRegMatConvert(&RxReg, &mat_Rx);  //Rotation matrix rotating around X axis (radian system)
    // pmRzRegMatConvert(&RzReg, &mat_Rz);
    // pmMatMatMult(&mat_Rz, &mat_Rx, &mat_Rxz);
    // if (zucmotConfig->safetyCfg.attitudesafety.conical_tip_choice == 0)  //TCP attitude are restricted
    // {
    //     to6_tool_verp_mat = mat_Rxz;
    // }
    // else
    // {
    //     tool_verp_rpy.y = zucmotConfig->tool_offset.a * PM_PI / 180.0;
    //     tool_verp_rpy.p = zucmotConfig->tool_offset.b * PM_PI / 180.0;
    //     tool_verp_rpy.r = zucmotConfig->tool_offset.c * PM_PI / 180.0;

    //     pmRpyMatConvert(&tool_verp_rpy, &tool_verp_mat);
    //     pmMatMatMult(&tool_verp_mat, &mat_Rxz, &to6_tool_verp_mat);
    // }
    // pmMatXyzConvert(&to6_tool_verp_mat, &tool_dir_xyz);
    // // MOTCMD_INFO("tool_to_6 rx ry rz is : %f %f %f \n", tool_dir_xyz.x * 180 / PM_PI, tool_dir_xyz.y * 180 / PM_PI, tool_dir_xyz.z * 180 / PM_PI);

    // double devia = zucmotConfig->safetyCfg.attitudesafety.deviation * PM_PI / 180.0;
    // double z_cone = 100;
    // double x_y_cone = z_cone * tan(devia) * 2;
    // // MOTCMD_INFO("x_y_cone : %f\n", x_y_cone);
    // PmRpy rpy_conical;
    // PmCartesian conical_z;
    // rpy_conical.y = zucmotConfig->safetyCfg.attitudesafety.conical_cenrpy[0] * PM_PI / 180.0;
    // rpy_conical.p = zucmotConfig->safetyCfg.attitudesafety.conical_cenrpy[1] * PM_PI / 180.0;
    // rpy_conical.r = zucmotConfig->safetyCfg.attitudesafety.conical_cenrpy[2] * PM_PI / 180.0;
    // PmRotationMatrix mat_conical;
    // pmRpyMatConvert(&rpy_conical, &mat_conical);
    // pmMatXyzConvert(&mat_conical, &cone_xyz);
    // // MOTCMD_INFO("cone rx ry rz is : %f %f %f \n", cone_xyz.x * 180 / PM_PI, cone_xyz.y * 180 / PM_PI, cone_xyz.z * 180 / PM_PI);
    // zucmotConfig->verp_safe_information.tool_cone_dir.x_y_cone = x_y_cone / 1000;
    // zucmotConfig->verp_safe_information.tool_cone_dir.z_cone = z_cone / 1000;

    // zucmotConfig->verp_safe_information.tool_cone_dir.cone_xyz = cone_xyz;
    // zucmotConfig->verp_safe_information.tool_cone_dir.tool_dir_xyz = tool_dir_xyz;

    // zucmot_config_change();
    return 0;
}

int CmdSetCollisionOption::process()
{
    CollisionOption ori_clsnOpt;
    ori_clsnOpt = zucmotConfig->safetyCfg.clsnOpt;
    zucmotConfig->safetyCfg.clsnOpt = clsnOpt_;
    MOTCMD_INFO("ZUCMOT_SET_COLLISION_OPTION: reactionType = %d, reboundAngle = %f, collisionMethod = %d\n",
                clsnOpt_.reactionType,
                clsnOpt_.reboundAngle,
                clsnOpt_.collisionMethod);
    //    tpManager_tpSetClsnOpt(zucmotConfig->safetyCfg.clsnOpt);
    unsigned int ori_crc = zucmotStatus->safetyCRC;
    zucmotStatus->safetyCRC = crc32((const UINT8*)&zucmotConfig->safetyCfg, sizeof(SafetyConfig));
    zucmot_config_change();
    if (ori_crc != zucmotStatus->safetyCRC && task_init_finish_flag == 1)
    {
        char str[MAX_ERROR_MSG_STR_LEN];
        snprintf(str,
                 sizeof(str),
                 "{\"fixed_key\":[\"%#x\", \"%#x\", \"%d\", \"%d\", \"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\", \"%d\", \"%d\", "
                 "\"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\", \"%.3f\"]}",
                 ori_crc,
                 zucmotStatus->safetyCRC,
                 ori_clsnOpt.collisionMethod,
                 ori_clsnOpt.reactionType,
                 ori_clsnOpt.reboundAngle,
                 ori_clsnOpt.reboundLength,
                 ori_clsnOpt.rebound_j_acc,
                 ori_clsnOpt.rebound_j_vel,
                 ori_clsnOpt.rebound_l_acc,
                 ori_clsnOpt.rebound_l_vel,
                 clsnOpt_.collisionMethod,
                 clsnOpt_.reactionType,
                 clsnOpt_.reboundAngle,
                 clsnOpt_.reboundLength,
                 clsnOpt_.rebound_j_acc,
                 clsnOpt_.rebound_j_vel,
                 clsnOpt_.rebound_l_acc,
                 clsnOpt_.rebound_l_vel);
        reportInfo(INFO_SAFETY_CONF_COLLISION_OPTION_CHANGED, "checksum changed # %s ", str);
    }
    return 0;
}
